/* eslint-disable */
import Layers from "../../lang/layers";
import Asserts from "@/lang/core/asserts.js";
import Text from "@/lang/layers/text.js";

/**
 * 格式化输出 字符串
 *
 * 如果是字符串，默认去除前后空白字符，其它类型保持原样
 *
 * @param val {*} 输入值
 * @returns {*}
 */
const formatString = (val) => {
    if (typeof val === 'string') {
        return val.trim();
    } else {
        return val;
    }
}

/**
 * 格式化输入 布尔值
 *
 * @param val 输入值
 * @returns {boolean}
 */
const parserBoolean = (val) => {
    return Layers.caseToBoolean(val);
}

/**
 * 格式化输入 字符串
 *
 * @param val 输入值
 * @returns {string}
 */
const parserString = (val) => {
    return Layers.caseToString(val);
}

/**
 * 格式化输入 数字
 *
 * @param val 输入值
 * @returns {number}
 */
const parserNumber = (val) => {
    return Layers.caseToNumber(val);
}

/**
 * 格式化输入 日期
 *
 * @param val 输入值
 * @returns {string}
 */
const parserDate = (val) => {
    return Text.date(val);
}

/**
 * 格式化输入 日期
 *
 * @param val 输入值
 * @returns {string}
 */
const parserDatetime = (val) => {
    return Text.datetime(val);
}

/**
 * 格式化输入 数组
 *
 * 如果非数组，则构造一个数组，将输入值放到数组第一位
 *
 * @param val 输入值
 * @returns {[any]}
 */
const parseArray = function (val) {
    return Layers.caseToArray(val);
}

/**
 * 默认配置
 *
 * 原样输入、输出，默认值为空字符串
 *
 * @param input {FormInput}
 * @constructor
 */
const DefaultWrapper = function (input) {
    input.defaultValue = '';
};

/**
 * 布尔值输入框
 *
 * 默认值为 false，入参格式化成 boolean 类型
 *
 * @param input {FormInput}
 * @constructor
 */
const BooleanWrapper = function (input) {
    input.setParser(parserBoolean);
    input.defaultValue = false;
};

/**
 * 数字输入框
 *
 * 输入值格式化成数字，默认值为空字符串
 *
 * @param input {FormInput}
 * @constructor
 */
const NumberWrapper = function (input) {
    input.setParser(parserNumber);
    input.defaultValue = '';
};

/**
 * 文本输入框
 *
 * 输入值格式化成字符串，默认值为空字符串
 *
 * @param input {FormInput}
 * @constructor
 */
const TextViewWrapper = function (input) {
    input.setParser(parserString);
    input.setFormatter(formatString);
    input.defaultValue = '';
};

/**
 * 多选
 *
 * 用逗号拼接，之后转为字符串，默认值为空数组
 *
 * @param input {FormInput}
 * @constructor
 */
const ArrayWrapper = function (input) {
    input.setParser(parseArray);
    input.defaultValue = [];
};

/**
 * 格式化 FormInput
 *
 * @param input {FormInput}
 * @constructor
 */
const DatePickerWrapper = function (input) {
    input.setParser(parserDate);
    input.defaultValue = '';
};

/**
 * 格式化 FormInput
 *
 * @param input {FormInput}
 * @constructor
 */
const DatetimePickerWrapper = function (input) {
    input.setParser(parserDatetime);
    input.defaultValue = '';
};

/**
 * 格式化 FormInput
 *
 * @param input {FormInput}
 * @constructor
 */
const DateRangeWrapper = function (input) {
    input.parse = function (val) {
        if (Layers.isBlank(val)) {
            return val;
        } else if (typeof val === 'string') {
            return val.split('~')
        } else {
            return val;
        }
    };
    input.format = function (val) {
        if (Layers.isEmpty(val)) {
            return [];
        } else {
            return [Text.date(val[0]), Text.date(val[1])];
        }
    }
};

/**
 * 格式化 FormInput
 * @param input {FormInput}
 * @constructor
 */
const DatetimeRangeWrapper = function (input) {
    input.parse = function (val) {
        if (Layers.isBlank(val)) {
            return val;
        } else if (Array.isArray(val)) {
            return val;
        } else if (typeof val === 'string') {
            return val.split('~')
        } else {
            return val;
        }
    };
    input.format = function (val) {
        if (Layers.isEmpty(val)) {
            return [];
        } else {
            return [Text.datetime(val[0]), Text.datetime(val[1])];
        }
    }
};

/**
 * 格式化 FormInput
 *
 * @param input {FormInput}
 * @constructor
 */
const CheckTreeWrapper = function (input) {
    input.defaultValue = function () {
        return [];
    };
    input.parse = function (val) {
        return Layers.caseToArray(val);
    };
    input.format = function (val) {
        return Layers.caseToString(val);
    }
};


/**
 * FormInput 配置列表
 */
const wrappers = {
    // 数字输入
    Number: NumberWrapper,

    // 字符输入：文本框、文本域、富文本框
    TextView: TextViewWrapper,
    Textarea: TextViewWrapper,
    Editor: TextViewWrapper,

    // 布尔输入：开关、单选框
    Switch: BooleanWrapper,
    Checkbox: BooleanWrapper,

    // 原样输入，需要手动处理数据格式
    Select: DefaultWrapper,
    SelectTree: DefaultWrapper,
    RadioGroup: DefaultWrapper,

    // 数组输入：树、复选框
    CheckTree: DefaultWrapper,
    CheckboxGroup: DefaultWrapper,

    // 日期输入：
    DateRange: DateRangeWrapper,
    DatePicker: DatePickerWrapper,
    DatetimeRange: DatetimeRangeWrapper,
    DatetimePicker: DatetimePickerWrapper,

    // 文件上传：有专门的设计，无须处理
    File: DefaultWrapper,
    Image: DefaultWrapper,
    Uploader: DefaultWrapper
};

/**
 * 表单打包器
 *
 * 理想状态下，不同的组件应当继承自 FormInput，详见 form-item.js 中的源码。
 *
 * vue 环境下，渲染过程拆分到了多个组件中，无法通过继承实现，
 * 因此，采用 override 的方式实现，对象创建之后，覆盖原有的函数。
 * ------------------------------------------------------------------------------
 */
export default class FormWrapper {
    /**
     * 初始化组件
     *
     * @param input {FormInput} 输入组件
     * @param type {string} 数组组件类型
     */
    static wrap(input, type) {
        if (Layers.isNotEmpty(type)) {
            input.type = type;
        }
        Asserts.notEmpty(input.type, 'form-input type is undefined!')
        let wrapper = wrappers[input.type];
        if (wrapper === undefined) {
            wrapper = DefaultWrapper;
            console.error('Wrapper is undefined, using default: ' + input.type);
        }
        wrapper(input);
    }
};
